package com.imut.lagain.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.imut.lagain.entity.MemoryCapsule;
import com.imut.lagain.repository.MemoryCapsuleRepository;
import com.imut.lagain.service.IMemoryCapsuleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * 记忆胶囊服务实现类
 */
@Service
@Transactional
public class MemoryCapsuleServiceImpl extends ServiceImpl<MemoryCapsuleRepository, MemoryCapsule> implements IMemoryCapsuleService {
    private static final Logger log = LoggerFactory.getLogger(MemoryCapsuleServiceImpl.class);

    
    
    /**
     * 获取所有胶囊，按最后活跃时间倒序排列
     * @return 胶囊列表
     */
    @Transactional(readOnly = true)
    public List<MemoryCapsule> getAllCapsulesOrderByLastActiveTime() {
        QueryWrapper<MemoryCapsule> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted", false)
                   .orderByDesc("last_active_time");
        return this.list(queryWrapper);
    }
    
    /**
     * 创建新的记忆胶囊
     * @param userId 用户ID
     * @param title 标题
     * @param description 描述
     * @param coverImageUrl 封面图片URL
     * @param type 胶囊类型
     * @param openTime 开启时间
     * @param accessPassword 访问密码
     * @return 创建的胶囊
     */
    public MemoryCapsule createCapsule(Long userId, String title, String description, String coverImageUrl, 
                                      String type, LocalDateTime openTime, String accessPassword) {
        MemoryCapsule capsule = new MemoryCapsule();
        capsule.setUserId(userId);
        capsule.setTitle(title);
        capsule.setDescription(description);
        capsule.setCoverImageUrl(coverImageUrl);
        Integer typeCode;
        if (StringUtils.hasText(type)) {
            switch (type.toLowerCase()) {
                case "personal":
                    typeCode = 1;
                    break;
                case "shared":
                case "couple":
                case "family":
                case "friend":
                    typeCode = 2;
                    break;
                default:
                    typeCode = 1;
            }
        } else {
            typeCode = 1;
        }
        capsule.setType(typeCode);
        capsule.setStatus(1); // draft = 1
        capsule.setOpenTime(openTime);
        capsule.setAccessPassword(accessPassword);
        capsule.setShareCode(generateUniqueShareCode());
        capsule.setLastActiveTime(LocalDateTime.now());
        capsule.setCreateTime(LocalDateTime.now());
        capsule.setUpdateTime(LocalDateTime.now());
        capsule.setIsDeleted(false);
        
        boolean saved = this.save(capsule);
        if (saved) {
            log.info("Created new memory capsule: {} for user: {}", capsule.getId(), userId);
            return capsule;
        } else {
            log.error("Failed to create memory capsule for user: {}", userId);
            return null;
        }
    }
    
    /**
     * 更新胶囊的最后活跃时间
     * @param capsuleId 胶囊ID
     */
    public void updateLastActiveTime(Long capsuleId) {
        if (capsuleId == null) {
            return;
        }
        MemoryCapsule capsule = this.getById(capsuleId);
        if (capsule != null && !capsule.getIsDeleted()) {
            capsule.setLastActiveTime(LocalDateTime.now());
            capsule.setUpdateTime(LocalDateTime.now());
            this.updateById(capsule);
        }
    }
    
    /**
     * 根据ID获取胶囊详情
     * @param capsuleId 胶囊ID
     * @return 胶囊信息
     */
    @Transactional(readOnly = true)
    public MemoryCapsule getCapsuleById(Long capsuleId) {
        if (capsuleId == null) {
            return null;
        }
        MemoryCapsule capsule = this.getById(capsuleId);
        return (capsule != null && !capsule.getIsDeleted()) ? capsule : null;
    }
    
    /**
     * 根据用户ID获取胶囊列表
     * @param userId 用户ID
     * @param page 分页参数
     * @return 胶囊分页列表
     */
    @Transactional(readOnly = true)
    public IPage<MemoryCapsule> getCapsulesByUserId(Long userId, Page<MemoryCapsule> page) {
        if (userId == null) {
            return new Page<>();
        }
        return baseMapper.findByUserId(userId, page);
    }
    
    /**
     * 获取用户的胶囊列表
     * @param userId 用户ID
     * @param page 页码
     * @param size 每页大小
     * @return 胶囊分页列表
     */
    @Transactional(readOnly = true)
    public IPage<MemoryCapsule> getUserCapsules(Long userId, Integer page, Integer size) {
        if (userId == null) {
            return new Page<>();
        }
        Page<MemoryCapsule> pageParam = new Page<>(page, size);
        return baseMapper.findByUserId(userId, pageParam);
    }
    
    /**
     * 根据状态获取用户的胶囊列表
     * @param userId 用户ID
     * @param status 状态
     * @param page 页码
     * @param size 每页大小
     * @return 胶囊分页列表
     */
    @Transactional(readOnly = true)
    public IPage<MemoryCapsule> getUserCapsulesByStatus(Long userId, Integer status, Integer page, Integer size) {
        if (userId == null) {
            return new Page<>();
        }
        Page<MemoryCapsule> pageParam = new Page<>(page, size);
        QueryWrapper<MemoryCapsule> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId)
                   .eq("status", status)
                   .eq("is_deleted", false)
                   .orderByDesc("last_active_time");
        return this.page(pageParam, queryWrapper);
    }
    
    /**
     * 根据分享码获取胶囊
     * @param shareCode 分享码
     * @return 胶囊信息
     */
    @Transactional(readOnly = true)
    public MemoryCapsule getCapsuleByShareCode(String shareCode) {
        if (!StringUtils.hasText(shareCode)) {
            return null;
        }
        return baseMapper.findByShareCode(shareCode);
    }
    
    /**
     * 根据状态获取胶囊列表
     * @param status 状态
     * @param page 分页参数
     * @return 胶囊分页列表
     */
    @Transactional(readOnly = true)
    public IPage<MemoryCapsule> getCapsulesByStatus(String status, Page<MemoryCapsule> page) {
        if (!StringUtils.hasText(status)) {
            return new Page<>();
        }
        return baseMapper.findByStatus(status, page);
    }
    
    /**
     * 根据类型获取胶囊列表
     * @param type 类型
     * @param page 分页参数
     * @return 胶囊分页列表
     */
    @Transactional(readOnly = true)
    public IPage<MemoryCapsule> getCapsulesByType(String type, Page<MemoryCapsule> page) {
        if (!StringUtils.hasText(type)) {
            return new Page<>();
        }
        return baseMapper.findByType(type, page);
    }
    
    /**
     * 根据标题模糊查询胶囊
     * @param title 标题关键字
     * @param page 分页参数
     * @return 胶囊分页列表
     */
    @Transactional(readOnly = true)
    public IPage<MemoryCapsule> searchCapsulesByTitle(String title, Page<MemoryCapsule> page) {
        if (!StringUtils.hasText(title)) {
            return new Page<>();
        }
        return baseMapper.findByTitleLike(title, page);
    }
    
    /**
     * 获取即将开启的胶囊
     * @param beforeTime 时间范围
     * @return 胶囊列表
     */
    @Transactional(readOnly = true)
    public List<MemoryCapsule> getCapsulesAboutToOpen(LocalDateTime beforeTime) {
        if (beforeTime == null) {
            beforeTime = LocalDateTime.now().plusDays(1); // 默认1天内
        }
        return baseMapper.findCapsulesAboutToOpen(beforeTime);
    }
    
    /**
     * 获取指定时间范围内即将开启的胶囊
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 胶囊列表
     */
    @Transactional(readOnly = true)
    public List<MemoryCapsule> findCapsulesAboutToOpen(LocalDateTime startTime, LocalDateTime endTime) {
        if (startTime == null || endTime == null) {
            return List.of();
        }
        QueryWrapper<MemoryCapsule> queryWrapper = new QueryWrapper<>();
        queryWrapper.between("open_time", startTime, endTime)
                   .eq("status", "sealed")
                   .eq("is_deleted", false)
                   .orderByAsc("open_time");
        return this.list(queryWrapper);
    }
    
    /**
     * 获取已到开启时间的胶囊
     * @param currentTime 当前时间
     * @return 胶囊列表
     */
    @Transactional(readOnly = true)
    public List<MemoryCapsule> findCapsulesReadyToOpen(LocalDateTime currentTime) {
        if (currentTime == null) {
            currentTime = LocalDateTime.now();
        }
        return baseMapper.findCapsulesReadyToOpen(currentTime);
    }
    
    /**
     * 获取过期的临时胶囊
     * @param expireTime 过期时间
     * @return 胶囊列表
     */
    @Transactional(readOnly = true)
    public List<MemoryCapsule> findExpiredTempCapsules(LocalDateTime expireTime) {
        if (expireTime == null) {
            return List.of();
        }
        QueryWrapper<MemoryCapsule> queryWrapper = new QueryWrapper<>();
        queryWrapper.lt("create_time", expireTime)
                   .eq("type", "temp")
                   .eq("status", "sealed")
                   .eq("is_deleted", false)
                   .orderByAsc("create_time");
        return this.list(queryWrapper);
    }
    
    /**
     * 统计胶囊数量
     * @param userId 用户ID（null表示所有用户）
     * @param status 状态（null表示所有状态）
     * @param type 类型（null表示所有类型）
     * @return 胶囊数量
     */
    @Transactional(readOnly = true)
    public Long countCapsules(Long userId, String status, String type) {
        QueryWrapper<MemoryCapsule> wrapper = new QueryWrapper<>();
        if (userId != null) {
            wrapper.eq("user_id", userId);
        }
        if (StringUtils.hasText(status)) {
            wrapper.eq("status", status);
        }
        if (StringUtils.hasText(type)) {
            wrapper.eq("type", type);
        }
        wrapper.eq("is_deleted", 0);
        return baseMapper.selectCount(wrapper);
    }
    
    /**
     * 根据状态统计胶囊数量
     * @param status 胶囊状态
     * @return 胶囊数量
     */
    @Transactional(readOnly = true)
    public Long countByStatus(String status) {
        if (!StringUtils.hasText(status)) {
            return 0L;
        }
        Integer statusCode;
        switch (status.toLowerCase()) {
            case "draft":
            case "creating":
                statusCode = 1;
                break;
            case "sealed":
                statusCode = 2;
                break;
            case "opened":
                statusCode = 3;
                break;
            default:
                return 0L;
        }
        
        QueryWrapper<MemoryCapsule> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", statusCode)
                   .eq("is_deleted", false);
        return this.count(queryWrapper);
    }
    
    /**
     * 根据用户ID和状态查询胶囊列表
     * @param userId 用户ID
     * @param status 状态字符串（"sealed" 或 "opened"）
     * @return 胶囊列表
     */
    @Transactional(readOnly = true)
    public List<MemoryCapsule> findByUserIdAndStatus(Long userId, String status) {
        if (userId == null || !StringUtils.hasText(status)) {
            return List.of();
        }
        
        Integer statusCode;
        switch (status.toLowerCase()) {
            case "sealed":
                statusCode = 2; // 已封存
                break;
            case "opened":
                statusCode = 3; // 已开启
                break;
            default:
                throw new IllegalArgumentException("不支持的状态: " + status);
        }
        
        QueryWrapper<MemoryCapsule> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId)
                   .eq("status", statusCode)
                   .eq("is_deleted", false)
                   .orderByDesc("last_active_time");
        return this.list(queryWrapper);
    }
    
    /**
     * 更新胶囊状态
     * @param capsuleId 胶囊ID
     * @param status 新状态
     * @return 是否更新成功
     */
    public boolean updateCapsuleStatus(Long capsuleId, String status) {
        if (capsuleId == null || !StringUtils.hasText(status)) {
            return false;
        }
        Integer statusCode;
        switch (status.toLowerCase()) {
            case "draft":
            case "creating":
                statusCode = 1;
                break;
            case "sealed":
                statusCode = 2;
                break;
            case "opened":
                statusCode = 3;
                break;
            default:
                return false;
        }
        
        int result = baseMapper.updateStatus(capsuleId, statusCode);
        if (result > 0) {
            return true;
        }
        return false;
    }
    
    /**
     * 封存胶囊
     * @param capsuleId 胶囊ID
     * @return 是否封存成功
     */
    public boolean sealCapsule(Long capsuleId) {
        if (capsuleId == null) {
            return false;
        }
        LocalDateTime sealedTime = LocalDateTime.now();
        int result = baseMapper.updateSealedTime(capsuleId, sealedTime);
        if (result > 0) {
            updateCapsuleStatus(capsuleId, "sealed");
            return true;
        }
        return false;
    }
    
    /**
     * 软删除胶囊
     * @param capsuleId 胶囊ID
     * @return 是否删除成功
     */
    public boolean softDeleteCapsule(Long capsuleId) {
        if (capsuleId == null) {
            return false;
        }
        MemoryCapsule capsule = this.getById(capsuleId);
        if (capsule == null) {
            return false;
        }
        capsule.setIsDeleted(true);
        capsule.setUpdateTime(LocalDateTime.now());
        boolean result = this.updateById(capsule);
        if (result) {
        }
        return result;
    }
    
    /**
     * 恢复已删除的胶囊
     * @param capsuleId 胶囊ID
     * @return 是否恢复成功
     */
    public boolean restoreCapsule(Long capsuleId) {
        if (capsuleId == null) {
            return false;
        }
        MemoryCapsule capsule = this.getById(capsuleId);
        if (capsule == null) {
            return false;
        }
        capsule.setIsDeleted(false);
        capsule.setUpdateTime(LocalDateTime.now());
        boolean result = this.updateById(capsule);
        if (result) {
        }
        return result;
    }
    
    /**
     * 检查分享码是否存在
     * @param shareCode 分享码
     * @return 是否存在
     */
    @Transactional(readOnly = true)
    public boolean shareCodeExists(String shareCode) {
        if (!StringUtils.hasText(shareCode)) {
            return false;
        }
        return baseMapper.existsByShareCode(shareCode);
    }
    
    /**
     * 生成唯一的分享码
     * @return 分享码
     */
    private String generateUniqueShareCode() {
        String shareCode;
        int attempts = 0;
        do {
            shareCode = generateShareCode();
            attempts++;
        } while (shareCodeExists(shareCode) && attempts < 10);
        
        if (attempts >= 10) {
            shareCode = UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase();
        }
        
        return shareCode;
    }
    
    /**
     * 生成分享码
     * @return 8位随机字符串
     */
    private String generateShareCode() {
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 8; i++) {
            int index = (int) (Math.random() * chars.length());
            sb.append(chars.charAt(index));
        }
        return sb.toString();
    }
    
    /**
     * 验证访问密码
     * @param capsuleId 胶囊ID
     * @param password 密码
     * @return 是否验证成功
     */
    @Transactional(readOnly = true)
    public boolean validateAccessPassword(Long capsuleId, String password) {
        if (capsuleId == null) {
            return false;
        }
        MemoryCapsule capsule = this.getById(capsuleId);
        if (capsule == null || capsule.getIsDeleted()) {
            return false;
        }
        if (!StringUtils.hasText(capsule.getAccessPassword())) {
            return true;
        }
        
        return capsule.getAccessPassword().equals(password);
    }
    
    /**
     * 更新胶囊信息
     * @param capsuleId 胶囊ID
     * @param title 标题
     * @param description 描述
     * @param coverImageUrl 封面图片URL
     * @param type 胶囊类型
     * @param openTime 开启时间
     * @param accessPassword 访问密码
     * @return 是否更新成功
     */
    public boolean updateCapsule(Long capsuleId, String title, String description, String coverImageUrl, 
                                 String type, LocalDateTime openTime, String accessPassword) {
        if (capsuleId == null) {
            return false;
        }
        
        MemoryCapsule capsule = this.getById(capsuleId);
        if (capsule == null || capsule.getIsDeleted()) {
            return false;
        }
        
        if (StringUtils.hasText(title)) {
            capsule.setTitle(title);
        }
        if (StringUtils.hasText(description)) {
            capsule.setDescription(description);
        }
        if (StringUtils.hasText(coverImageUrl)) {
            capsule.setCoverImageUrl(coverImageUrl);
        }
        if (StringUtils.hasText(type)) {
            Integer typeCode;
            switch (type.toLowerCase()) {
                case "personal":
                    typeCode = 1;
                    break;
                case "shared":
                case "couple":
                case "family":
                case "friend":
                    typeCode = 2;
                    break;
                default:
                    typeCode = 1;
            }
            capsule.setType(typeCode);
        }
        if (openTime != null) {
            capsule.setOpenTime(openTime);
        }
        if (StringUtils.hasText(accessPassword)) {
            capsule.setAccessPassword(accessPassword);
        }
        
        capsule.setUpdateTime(LocalDateTime.now());
        return this.updateById(capsule);
    }
    
    /**
     * 更新胶囊信息
     * @param capsule 胶囊信息
     * @return 是否更新成功
     */
    public boolean updateCapsule(MemoryCapsule capsule) {
        if (capsule == null || capsule.getId() == null) {
            return false;
        }
        capsule.setUpdateTime(LocalDateTime.now());
        return this.updateById(capsule);
    }
    
    /**
     * 删除胶囊
     * @param capsuleId 胶囊ID
     * @return 是否删除成功
     */
    public boolean deleteCapsule(Long capsuleId) {
        if (capsuleId == null) {
            return false;
        }
        MemoryCapsule capsule = this.getById(capsuleId);
        if (capsule == null || capsule.getIsDeleted()) {
            return false;
        }
        capsule.setIsDeleted(true);
        capsule.setDeleteTime(LocalDateTime.now());
        capsule.setUpdateTime(LocalDateTime.now());
        return this.updateById(capsule);
    }
}
